package com.base.library.base

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.findViewTreeLifecycleOwner
import androidx.recyclerview.widget.RecyclerView
import androidx.viewbinding.ViewBinding
import com.base.library.BR
import com.base.library.entity.ItemDataBinding

open class BaseRecyclerAdapter<T>(
    private val itemBinding: ItemDataBinding?,
    list: Collection<T>? = null
) :
    RecyclerView.Adapter<BaseRecyclerAdapter.BaseViewHolder<T>>() {

    protected val mDataList: MutableList<T> by lazy {
        mutableListOf()
    }

    init {
        list?.let {
            mDataList.addAll(it)
        }
    }

    private var lifecycleOwner: LifecycleOwner? = null

    override fun getItemViewType(position: Int): Int {
        return super.getItemViewType(position)
    }

    open fun getItemBinding(viewType: Int): ItemDataBinding? = itemBinding
    fun getItemData(position: Int): T? {
        val size = mDataList.size
        if (position >= 0 && position <= size - 1) {
            return mDataList[position]
        }
        return null
    }

    fun getLastItemData(): T? {
        return getItemData(mDataList.size - 1)
    }

    fun getAllData(): MutableList<T> {
        return mDataList
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<T> {
        val item =
            getItemBinding(viewType) ?: throw RuntimeException("item binding can not be null,viewType:$viewType")
        if (lifecycleOwner == null) {
            lifecycleOwner = parent.findViewTreeLifecycleOwner()
        }
        return BaseViewHolder(
            DataBindingUtil.inflate(
                LayoutInflater.from(parent.context), item.layoutId, parent, false
            ), item
        )
    }

    override fun getItemCount() = mDataList.size

    override fun onBindViewHolder(holder: BaseViewHolder<T>, position: Int) {
//        val data = mDataList[holder.adapterPosition]
        val data = mDataList[position]
        holder.bindData(position, data, itemCount, lifecycleOwner)
    }

    @SuppressLint("NotifyDataSetChanged")
    fun flushData(data: Collection<T>?) {
        this.mDataList.clear()
        data?.let {
            this.mDataList.addAll(data)
        }
        notifyDataSetChanged()
    }

    fun addItem(data: T?) {
        data?.let {
            this.mDataList.add(data)
            notifyItemInserted(mDataList.size)
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    fun addItems(dataList: Collection<T>?) {
        if (dataList?.isNotEmpty() == true) {
            this.mDataList.addAll(dataList)
            notifyDataSetChanged()
        }
    }

    fun removeItem(data: T?) {
        data?.let {
            val index = this.mDataList.indexOf(data)
            if (this.mDataList.remove(data)) {
                notifyItemRemoved(index)
            }
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    fun removeItems(dataList: Collection<T>?) {
        if (dataList?.isNotEmpty() == true) {
            this.mDataList.removeAll(dataList)
            notifyDataSetChanged()
        }
    }

    open class BaseViewHolder<T>(
        val binding: ViewDataBinding,
        private val itemBinding: ItemDataBinding
    ) :
        RecyclerView.ViewHolder(binding.root) {
        open fun bindData(
            position: Int,
            data: T,
            size: Int,
            lifecycleOwner: LifecycleOwner?
        ): ViewBinding {
            binding.setVariable(itemBinding.BRId, data)
            binding.setVariable(BR.isLastItem, position == size - 1)
            itemBinding.vm?.let {
                binding.setVariable(BR.vm, it)
            }
            binding.lifecycleOwner = lifecycleOwner
            binding.executePendingBindings()
            return binding
        }
    }
}